﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.XPath;

namespace XPathPlugin.XPathExpressionUtils
{
    static class XPathExpressionNormalizer
    {        
        /// <summary>
        /// Normalize expression - removes nesting spaces and parenthesis
        /// </summary>
        /// <param name="expression">expression to normalize</param>
        /// <returns>string</returns>
        public static string Normalize(string expression)
        {            
            if (expression == null)
                return null;

            expression = RemoveNestingSpaces(expression);
            expression = RemoveNestingParenthesis(expression);

            return expression;
        }

        /// <summary>
        /// Removes nesting spaces
        /// </summary>
        /// <param name="expression">expression to process</param>
        /// <returns>string</returns>
        public static string RemoveNestingSpaces(string expression)
        {
            if (expression == null)
                return null;
            
            expression = expression.Trim();
            
            char symbolBefore = '\0';
            char quote = '\0';            
            string proccessedExpression = "";            
            bool isSyntax = true;            

            foreach(char symbol in expression.ToCharArray())
            {                
                if (symbol == '\'' || symbol == '"')
                {
                    if (quote == '\0')
                    {
                        quote = symbol;
                        isSyntax = false;
                    }

                    else if (symbol == quote)
                    {
                        quote = '\0';
                        isSyntax = true;                        
                    }
                }

                if (isSyntax && (!IsWhiteSpace(symbolBefore) || !IsWhiteSpace(symbol)))
                    proccessedExpression += symbol;

                else if (!isSyntax)
                    proccessedExpression += symbol;
                                
                symbolBefore = symbol;
            }

            return proccessedExpression;
        }


        /// <summary>
        /// Removes nesting parenthesis
        /// </summary>
        /// <param name="expression">expression to process</param>
        /// <returns>string</returns>
        public static string RemoveNestingParenthesis(string expression)
        {
            if (expression == null)
                return null;

            expression = expression.Trim();

            bool canRemoveParens = expression.StartsWith("(") && expression.EndsWith(")");

            while (canRemoveParens)
            {
                expression = expression.Substring(1, expression.Length - 2).Trim();
                canRemoveParens = expression.StartsWith("(") && expression.EndsWith(")");
            }

            return expression;
        }

        /// <summary>
        /// Returns true whether character is whitespace
        /// </summary>
        /// <param name="c">character to check</param>
        /// <returns>bool</returns>
        private static bool IsWhiteSpace(char c)
        {
            return c == ' ' || c == '\n' || c == '\t' || c == '\r';
        }
    }
}
